import tuio
import time
import math
from couchdb.client import Server

server=Server('http://blanu.net/')

try:
  db=server.create('nui-map')
except:
  db=server['nui-map']

#print 'db: ', db

docid='gestures'
try:
  db[docid]={'gestures': []}
  doc=db[docid]
  #print 'docid:', docid
except:
  doc=db[docid]
  doc['gestures']=[]
  db[docid]=doc

tracking = tuio.Tracking()
#print "loaded profiles:", tracking.profiles.keys()
#print "list functions to access tracked objects:", tracking.get_helpers()

oids=set()
nids=set()
movers={}
origins={}
gestures=[]
gid=0

def distance(a, b):
  print 'distance:', a, b
  return math.sqrt(((b[0]-a[0])**2)+((b[1]-a[1])**2))

def trim(i):
#  return int(i*100)
  return i*100
    
try:
    while 1:
        tracking.update()
        dir(tracking)
        for obj in tracking.cursors():
            nids.add(obj)
#        print nids, oids, nids==oids
        added=nids-oids
        removed=oids-nids
        same=nids&oids

        changed=False

        for obj in added:
          print 'adding finger', [trim(obj.xpos), trim(obj.ypos)]
          origins[obj.sessionid]=[trim(obj.xpos), trim(obj.ypos)]
        for obj in same: # test for movers
          if trim(obj.xpos)!=origins[obj.sessionid][0] or trim(obj.ypos)!=origins[obj.sessionid][1]:
            #print 'moving finger', [trim(obj.xpos), trim(obj.ypos)]
            movers[obj.sessionid]=[trim(obj.xpos), trim(obj.ypos)]
        for obj in removed:
          if changed:
            break
          print 'removing finger', [trim(obj.xpos), trim(obj.ypos)]
          if obj.sessionid in movers.keys(): # gesture triggered
            #print 'lost mover:', obj.sessionid
            if len(movers)==1: # One-finger drag
              dx=trim(obj.xpos)-origins[obj.sessionid][0]
              dy=trim(obj.ypos)-origins[obj.sessionid][1]                
              gesture={'id': gid, 'type': 'swipe', 'vector': [dx, dy]}
              print 'swipe:', gesture
              gestures.append(gesture)
              gid=gid+1
              changed=True
            elif len(movers)==2: # Two-finger drag
              print 'detected pinch', [trim(obj.xpos), trim(obj.ypos)], movers
              oa=origins[obj.sessionid]
              if(movers.keys()[0]==obj.sessionid):
                other=movers.keys()[1]
              else:
                other=movers.keys()[0]
              ob=origins[other]
              fa=[trim(obj.xpos), trim(obj.ypos)]
              fb=movers[other]
              #del origins[other]
              print 'Calculating distance with', oa, ob, 'vs.', oa, [trim(obj.xpos), trim(obj.ypos)]
              d1=distance(oa, ob);
              d2=distance(fa, fb);
              print 'distance:', d1, d2, d2-d1, d2/d1
              diff=d2-d1
              t=0.1
              if diff>t:
                scale=1
              elif diff<-t:
                scale=-1
              else:
                scale=0
                print 'Ignoring weak pinch'
              if scale!=0:
                gesture={'id': gid, 'type': 'pinch', 'scale': scale}
                print 'pinch:', gesture
                gestures.append(gesture)
                gid=gid+1
              changed=True
          del origins[obj.sessionid]  

        if changed:
          movers={}
          while len(gestures)>10:
            del gestures[0]
          doc['gestures']=gestures
          db[docid]=doc
          
        tmp=oids
        oids=nids
        nids=tmp
        nids.clear()
#        time.sleep(1)
except KeyboardInterrupt:
    tracking.stop()
